﻿using System;
using System.Collections.Generic;
using Caramel.Linq;

namespace Caramel.Entities.Testing
{
	public class EntitySpecification<T> where T : class, IEntity, new()
	{
		private IList<Property<T>> _properties;

		public EntitySpecification()
		{
			_properties = new List<Property<T>>();
		}

		public T Verify()
		{
			T transientEntity = new T();

			_properties.
				Each(
					p =>
					p.SetValue(transientEntity)
				);

			UnitOfWork.Commit(() => Repository<T>.Save(transientEntity));

			var id = ((IEntity)transientEntity).ID;

			return
				UnitOfWork.
					ReadOnly<T>(
						() =>
						{
							var persistentEntity = Repository<T>.Get(id);
					
							_properties.
								Each(
									p => 
									p.
										CheckValue(
											transientEntity,
											persistentEntity
										)
								);

							return persistentEntity;
						}
					);
		}

		public EntitySpecification<T> RegisterCheckedProperty(Property<T> property)
		{
			_properties.Add(property);

			return this;
		}
	}
}
